#coding=utf-8
from decimal import Decimal
from django.db import models

from stsettings import DIRNAME
from stutils import float2dec,data2csv

from webscrapper.price import get_histprice, get_todayprice
from webscrapper.tradableshare import get_ts
from webscrapper.stcode import stcode_from_sse

from stvalidator import *

HISTPRICEDIR = DIRNAME + '/data/histprice'

class Stcode(models.Model):

    code = models.CharField(max_length=6)
    name = models.CharField(max_length=20)
    
    oldname = models.CharField(max_length=20, null=True, blank=True)
    
    created = models.DateField(auto_now_add=True)
    modified = models.DateField(auto_now=True)
    
    class Admin:pass
    
    def __unicode__(self):
        return "%s(%s)"%(self.name, self.code)
	
def stcode2db():
        
    cns = stcode_from_sse()
    
    for c,n in cns:
        try:
            isValidStcode(c)
            
            try:
                stcode = Stcode.objects.get(code=c)
            except Stcode.DoesNotExist:
                Stcode(code=c,name=n).save()
                continue
            #check if name is needed update
            if stcode.name != n:
                stcode.oldname = stcode.name
                stcode.name = n
                stcode.save()
                
        except ValidationError,e:
            print e
            continue

class Share(models.Model):
    
    code = models.CharField(max_length=6, unique=True)
    name = models.CharField(max_length=20)
    
    ipo = models.DateField(null=True,blank=True)
    
    def __unicode__(self):
        return "%s(%s)"%(self.name, self.code)
        
    class Admin:
        pass
    
    def histprice2db(self):    
        
        head = ["日期", "开盘价",	"最高价", "收盘价", "最低价","交易量(手)", "交易金额(万元)"]
        data = get_histprice(self.code, self.ipo)
        
        #put data into csv file
        fn= '%s/%s.csv'%(HISTPRICEDIR , self.code)
        data2csv(data, head, fn)
        
        #validation
        for d in data:
            isValidPricefromSina(d)
        
        #data 2 db
        pre = None
        for d in data:
            
            e = Exday(share=self, date=d[0])   
            if pre: e.pre = pre
            e.save()
            pre = e
            
            v = int(Decimal( d[5] ) * 100 )
            a = int(Decimal( d[6] ) * 10000 )
            
            dd = [float2dec(i, 2) for i in d[1:5]]
            p = Price(exday=e, start=dd[0], high=dd[1], end=dd[2], low=dd[3], volume=v, amount=a )
            p.save()

    def todayprice2db(self):
        data = get_todayprice(self.code)
        isValidPricefromSina(data)
        
        e = Exday(share=self, date=data[0])
        try:
            pre = self.exday_set.latest('date')
        except Exday.DoesNotExist:
            pre = None
        if pre: e.pre = pre
        e.save()
        
        d = data
        v = int(Decimal( d[5] ) * 100 )
        a = int(Decimal( d[6] ) * 10000 )
        
        dd = [float2dec(i, 2) for i in d[1:5]]
        p = Price(exday=e, start=dd[0], high=dd[1], end=dd[2], low=dd[3], volume=v, amount=a )
        p.save()
        
    def ts2db(self):
        data = get_ts(self.code)
    
        for d in data:
            isValidDate(d[0])
    
        for d in data:
            q = int(d[1])
        
            if q <= 0 :
                print '%s(%s)流通A股数量:%s'%(code, d[0], d[1])
                continue
            
            #check 是否数据已经存在
            try:
                self.tradableshare_set.get(date=d[0])
            except TradableShare.DoesNotExist,e:
                t = TradableShare( date=d[0], quantity=int(d[1]))
                self.tradableshare_set.add(t)
            
            
            
    def get_ts(self, date=None):
        if not date:
            return self.tradableshare_set.latest('date').quantity
        
        for t in self.tradableshare_set.all().order_by('-date'):
            if date >= t.date.isoformat():
                return t.quantity
                
    ts = property(fget=get_ts)
                        
def create_a_share(code):
    from webscrapper.ipo import get_ipo
    from stvalidator import isValidExdate,ValidationError
    
    try:
        s = Share.objects.get(code=code)
        if s :
            print "Share %s is alreadly in db"%s
            return
    except Share.DoesNotExist,e:
        pass
        
    try:
        name = Stcode.objects.get(code=code).name
    except Stcode.DoesNotExist,e:
        print "No Share whose code is %s in db stcode"%code
        return
        
    i = get_ipo(code)
    try:
        isValidExdate(i)
    except ValidationError,e:
        print code
        print e
        return 
    
    s = Share(code=code, name=name, ipo=i)
    s.save()
    
    return s
    
def shares2db():
    codes = [s.code for s in Stcode.objects.all()]      
    for c in codes:
        create_a_share(c)
        
         
class Exday(models.Model):
    
    date = models.DateField()
    share = models.ForeignKey('Share')
    pre = models.ForeignKey('self', unique=True, null=True, blank=True)
    
    def get_nextday(self):
        a = self.exday_set.all()
        if a:
            return a[0]
        return None
    next=property(fget=get_nextday)
    
    def get_price(self):
        a = self.price_set.all()
        if a:
            return a[0]
        return None
    price=property(fget=get_price)
    
    def __unicode__(self):
        jyr = unicode('交易日', 'u8')
        return "%s:%sof%s"%(self.date, jyr, self.share)
    
    class Admin:pass
        
class Price(models.Model):
    exday = models.ForeignKey('Exday', unique=True)
    
    start = models.DecimalField( max_digits=8, decimal_places=2, null=True, blank=True)
    end = models.DecimalField( max_digits=8, decimal_places=2, null=True, blank=True)
    
    low = models.DecimalField( max_digits=8, decimal_places=2, null=True, blank=True)
    high = models.DecimalField( max_digits=8, decimal_places=2, null=True, blank=True)
    
    volume = models.IntegerField()
    amount = models.IntegerField()
    
    change = models.DecimalField( max_digits=6, decimal_places=2, null=True, blank=True )
    hsl = models.DecimalField( max_digits=6, decimal_places=2, null=True, blank=True )
    fluctuation = models.DecimalField( max_digits=6, decimal_places=2, null=True, blank=True )
    
    def get_change(self):
        '''涨跌'''  
        pre = self.exday.pre
        if not pre:return None
        
        pe = pre.price.end
        change = ( self.end - pe )/ pe * 100
        change = float2dec(change, 2)
        
        return change
    
    def get_hsl(self):
        '''换手率'''
        d = self.exday.date.isoformat()
        ts = self.exday.share.get_ts(d)
        
        hsl = self.volume / float(ts) * 100
        hsl = float2dec(hsl, 2)
        
        return hsl
        
    def get_fluctuation(self):
        '''波动幅度'''
        f = ( self.high - self.low ) / self.end * 100
        f = float2dec(f, 2)
        return f
        
    def save(self):
        self.change = self.get_change()   
        self.hsl = self.get_hsl()
        self.fluctuation = self.get_fluctuation()
        super(Price, self).save()
        
    def __unicode__(self):
        jyr = unicode('交易日', 'u8')
        jgxx = unicode('的价格信息', 'u8')
        
        return "%s%s on %s(%s)"%(self.exday.share.name, jgxx, jyr, self.exday.date)
        
    class Admin:pass

class TradableShare(models.Model):
    
    share = models.ForeignKey('Share')
    date = models.DateField()
    quantity = models.IntegerField()
    
    created = models.DateField(auto_now_add=True)
    
    def __unicode__(self):
        ltag = unicode('流通A股数量', 'u8')
        return "%s of %s since %s"%(ltag, self.share.name, self.date )
        
    class Admin:pass
